home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / src / viewing.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  7KB  |  320 lines

  1. #include "vogl.h"
  2.  
  3. /* --------------------------------------------------------------------- */
  4.  
  5. #ifdef    TC
  6.  
  7. extern    double    cos();
  8. extern    double    sin();
  9. extern    double    asin();
  10. extern    double    sqrt();
  11. extern    double    fabs();
  12.  
  13. #else 
  14.  
  15. #include <math.h>
  16.  
  17. #endif
  18.  
  19. /*
  20.  * NOTE: the words hither and yon are used in this file instead of near and far
  21.  * as they are keywords on some PC compilers (groan). Change them back at your 
  22.  * on peril.
  23.  */
  24.  
  25. #define    SQ(a)    ((a)*(a))
  26. #define COT(a)    ((float)(cos((double)(a)) / sin((double)(a))))
  27.  
  28. /* ---------------------------------------------------------------------
  29.  * Prototypes:
  30.  */
  31. #ifdef __PROTOTYPE__
  32. static void normallookat( float, float, float, float,  /* viewing.c       */
  33.    float, float);
  34. #else    /* __PROTOTYPE__ */
  35. static void normallookat();                            /* viewing.c       */
  36. #endif    /* __PROTOTYPE__ */
  37.  
  38. /* ---------------------------------------------------------------------
  39.  * Source Code:
  40.  */
  41.  
  42. /*
  43.  * polarview
  44.  *
  45.  * Specify the viewer's position in polar coordinates by giving
  46.  * the distance from the viewpoint to the world origin, 
  47.  * the azimuthal angle in the x-y plane, measured from the y-axis,
  48.  * the incidence angle in the y-z plane, measured from the z-axis,
  49.  * and the twist angle about the line of sight. Note: that unlike
  50.  * in VOGLE we are back to tenths of degrees.
  51.  *
  52.  */
  53. void polarview(
  54.   Coord dist,
  55.   Angle azim,
  56.   Angle inc,
  57.   Angle twist)
  58. {
  59. if (!vdevice.initialised) 
  60. verror("polarview: vogl not initialised");
  61.  
  62. translate(0.0, 0.0, -dist);
  63. rotate((Angle) -twist, (char) 'z');
  64. rotate((Angle) -inc,   (char) 'x');
  65. rotate((Angle) -azim,  (char) 'z');
  66. }
  67.  
  68. /* ------------------------------------------------------------------------ */
  69.  
  70. /*
  71.  * normallookat
  72.  *
  73.  *    do the standard lookat transformation.
  74.  */
  75. static void normallookat(
  76.   float vx,
  77.   float vy,
  78.   float vz,
  79.   float px,
  80.   float py,
  81.   float pz)
  82. {
  83. float    l2, l3, sintheta, sinphi, costheta, cosphi;
  84. Matrix    tmp;
  85.  
  86. l2 = sqrt((double)(SQ((px - vx)) + SQ((pz - vz))));
  87. l3 = sqrt((double)(SQ((px - vx)) + SQ((py - vy)) + SQ((pz - vz))));
  88.  
  89. if (l3 != 0.0) {
  90.     sinphi = (vy - py) / l3;
  91.     cosphi = l2 / l3;
  92.  
  93.     /*
  94.      * Rotate about X by phi
  95.      */
  96.     identmatrix(tmp);
  97.     tmp[1][1] = tmp[2][2] = cosphi;
  98.     tmp[1][2] = sinphi;
  99.     tmp[2][1] = -sinphi;
  100.     multmatrix(tmp);
  101.     }
  102.  
  103. if (l2 != 0.0) {
  104.     sintheta = (px - vx) / l2;
  105.     costheta = (vz - pz) / l2;
  106.  
  107.     /*
  108.      * Rotate about Y by theta
  109.      */
  110.     identmatrix(tmp);
  111.     tmp[0][0] = tmp[2][2] = costheta;
  112.     tmp[0][2] = -sintheta;
  113.     tmp[2][0] = sintheta;
  114.     multmatrix(tmp);
  115.     }
  116. }
  117.  
  118. /* ------------------------------------------------------------------------ */
  119.  
  120. /*
  121.  * lookat
  122.  *
  123.  * Specify the viewer's position by giving a viewpoint and a 
  124.  * reference point in world coordinates. A twist about the line
  125.  * of sight may also be given.  Note that unlike in VOGLE we are
  126.  * back to tenths of degrees.
  127.  */
  128. void lookat(
  129.   Coord vx,
  130.   Coord vy,
  131.   Coord vz,
  132.   Coord px,
  133.   Coord py,
  134.   Coord pz,
  135.   Angle twist)
  136. {
  137. if (!vdevice.initialised) 
  138. verror("lookat: vogl not initialised");
  139.  
  140. rotate((Angle) -twist, (char) 'z');
  141.  
  142. normallookat(vx, vy, vz, px, py, pz);
  143.  
  144. translate(-vx, -vy, -vz);
  145. }
  146.  
  147. /* ------------------------------------------------------------------------ */
  148.  
  149. /*
  150.  * perspective
  151.  *
  152.  * Specify a perspective viewing pyramid in world coordinates by
  153.  * giving a field of view, aspect ratio, and the locations of the 
  154.  * near(hither) and far(yon) clipping planes in the z direction. Note
  155.  * that unlike in VOGLE we are back to tenths of degrees.
  156.  */
  157. void perspective(
  158.   Angle ifov,
  159.   float aspect,
  160.   Coord hither,
  161.   Coord yon)
  162. {
  163. Matrix        mat;
  164. float        fov;
  165.  
  166. if (!vdevice.initialised)
  167. verror("perspective: vogl not initialised");
  168.  
  169. if (aspect == 0.0)
  170. verror("perspective: can't have zero aspect ratio!");
  171.  
  172. if ((yon - hither) == 0.0)
  173. verror("perspective: near clipping plane same as far one.");
  174.  
  175. if (ifov == 0 || ifov == 1800)
  176. verror("perspective: bad field of view passed.");
  177.  
  178. fov = ifov / 10.0;
  179. identmatrix(mat);
  180.  
  181. mat[0][0] = COT((D2R * fov / 2.0)) / aspect;
  182. mat[1][1] = COT((D2R * fov / 2.0));
  183.  
  184. mat[2][2] = -(yon + hither) / (yon - hither);
  185. mat[2][3] = -1;
  186. mat[3][2] = -2.0 * yon * hither / (yon - hither);
  187. mat[3][3] = 0;
  188.  
  189. loadmatrix(mat);
  190. }
  191.  
  192. /* ------------------------------------------------------------------------ */
  193.  
  194. /*
  195.  * window
  196.  *
  197.  * Specify a perspective viewing pyramid in world coordinates by
  198.  * giving a rectangle at the near clipping plane and the location
  199.  * of the far clipping plane.
  200.  *
  201.  */
  202. void window(
  203.   Coord left,
  204.   Coord right,
  205.   Coord bottom,
  206.   Coord top,
  207.   Coord hither,
  208.   Coord yon)
  209. {
  210. Matrix        mat;
  211.  
  212. if (!vdevice.initialised)
  213. verror("window: vogl not initialised");
  214.  
  215. if ((right - left) == 0.0)
  216. verror("window: left clipping plane same as right one.");
  217.  
  218. if ((top - bottom) == 0.0)
  219. verror("window: bottom clipping plane same as top one.");
  220.  
  221. if ((yon - hither) == 0.0)
  222. verror("window: near clipping plane same as far one.");
  223.  
  224. identmatrix(mat);
  225.  
  226. mat[0][0] = 2.0 * hither / (right - left);
  227. mat[1][1] = 2.0 * hither / (top - bottom);
  228. mat[2][0] = (right + left) / (right - left);
  229. mat[2][1] = (top + bottom) / (top - bottom);
  230. mat[2][2] = -(yon + hither) / (yon - hither);
  231. mat[2][3] = -1.0;
  232. mat[3][2] = -2.0 * yon * hither / (yon - hither);
  233. mat[3][3] = 0.0;
  234.  
  235. loadmatrix(mat);
  236. }
  237.  
  238. /* ------------------------------------------------------------------------ */
  239.  
  240. /*
  241.  * ortho
  242.  *
  243.  * Define a three dimensional viewing box by giving the left,
  244.  * right, bottom and top clipping plane locations and the distances
  245.  * along the line of sight to the near and far clipping planes.
  246.  *
  247.  */
  248. void ortho(
  249.   Coord left,
  250.   Coord right,
  251.   Coord bottom,
  252.   Coord top,
  253.   Coord hither,
  254.   Coord yon)
  255. {
  256. Matrix        mat;
  257.  
  258. if (!vdevice.initialised)
  259. verror("ortho: vogl not initialised");
  260.  
  261. if ((right - left) == 0.0)
  262. verror("ortho: left clipping plane same as right one.");
  263.  
  264. if ((top - bottom) == 0.0)
  265. verror("ortho: bottom clipping plane same as top one.");
  266.  
  267. if ((yon - hither) == 0.0)
  268. verror("ortho: near clipping plane same as far one.");
  269.  
  270. identmatrix(mat);
  271.  
  272. mat[0][0] = 2.0 / (right - left);
  273. mat[1][1] = 2.0 / (top - bottom);
  274. mat[2][2] = -2.0 / (yon - hither);
  275. mat[3][0] = -(right + left) / (right - left);
  276. mat[3][1] = -(top + bottom) / (top - bottom);
  277. mat[3][2] = -(yon + hither) / (yon - hither);
  278.  
  279. loadmatrix(mat);
  280. }
  281.  
  282. /* ------------------------------------------------------------------------ */
  283.  
  284. /*
  285.  * ortho2
  286.  *
  287.  * Specify a two dimensional viewing rectangle. 
  288.  *
  289.  */
  290. void ortho2(
  291.   Coord left,
  292.   Coord right,
  293.   Coord bottom,
  294.   Coord top)
  295. {
  296. Matrix    mat;
  297.  
  298. if (!vdevice.initialised) 
  299. verror("ortho2: vogl not initialised");
  300.  
  301. identmatrix(mat);
  302.  
  303. if ((right - left) == 0.0)
  304. verror("ortho2: left clipping plane same as right one.");
  305.  
  306. if ((top - bottom) == 0.0)
  307. verror("ortho2: bottom clipping plane same as top one.");
  308.  
  309. mat[0][0] = 2.0 / (right - left);
  310. mat[1][1] = 2.0 / (top - bottom);
  311. mat[2][2] = -1.0;
  312. mat[3][0] = -(right + left) / (right - left);
  313. mat[3][1] = -(top + bottom) / (top - bottom);
  314.  
  315. loadmatrix(mat);
  316. }
  317.  
  318. /* ------------------------------------------------------------------------ */
  319.  
  320.